import isPlainObject from '../utils/isPlainObject.js';

/**
 * 创建store容器
 * @param {Function} reducer 处理action，返回新的state
 * @param {*} preloadedState 预加载的state
 * @param {Function} enhancer 增强store
 * @returns store
 */
export default function createStore(reducer, preloadedState, enhancer) {
  if (typeof reducer !== 'function') {
    throw new Error('Expected the root reducer to be a function.');
  }

  if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
    enhancer = preloadedState;
    preloadedState = undefined;
  }

  if (typeof enhancer !== 'undefined') {
    if (typeof enhancer !== 'function') {
      throw new Error('Expected the enhancer to be a function. ');
    }

    return enhancer(createStore)(reducer, preloadedState);
  }

  // 当前store的状态
  let currentState = preloadedState;
  // 订阅者存储列表
  let currentListeners = [];
  
  /**
   * 获取当前状态
   * @returns 
   */
  function getState() {
    return currentState;
  }

  /**
   * 1、触发reducer函数，更新state
   * 2、状态变更时，触发订阅事件
   * @param {Object} action 
   */
  function dispatch(action) {
    if (!isPlainObject(action)) {
      throw new Error('Actions must be plain objects. ');
    }

    // 更新state
    currentState = reducer(currentState, action);

    // 触发订阅
    for (let i = 0, len = currentListeners.length; i < len; i++) {
      const listener = currentListeners[i];
      listener();
    }
  }

  /**
   * 订阅状态变化
   * @param {Function} listener 订阅者
   * @return {Function} 取消订阅函数
   */
  function subscribe(listener) {
    currentListeners.push(listener);

    /**
     * 取消订阅
     */
    return function() {
      // 订阅者列表中是否存在listener
      const index = currentListeners.indexOf(listener);

      // 不存在，直接返回
      if (index === -1) {
        return;
      }

      // 删除订阅者
      currentListeners.splice(index, 1);
    };
  }

  // 初始化state
  dispatch({ type: '@redux/initState' });

  // 返回store
  return {
    dispatch,
    getState,
    subscribe,
  };
}